package main

import (
	"math/rand"
	"os"
	"strings"
	"time"
)

const (
	permutationsSourceFile = "./data/permutations.txt"
)

var (
	NodeItemBeautifyTextMapper = map[int]string{
		0: "TOP",
		1: "JUG",
		2: "MID",
		3: "ADC",
		4: "SUP",
	}
)

type TreeNode struct {
	Val         string
	ChildNodes  []*TreeNode
	ChildMapper map[string]int
}

// AddLanes adds lanes to the lane tree
// the value of val like "a,b,c,d,e|b,a,d,e,c|c,d,e,a,b|d,e,b,c,a|e,c,a,b,d"
func (lt *TreeNode) AddLanes(val string) {
	lanes := strings.Split(val, "|")
	root := lt

	for _, lane := range lanes {
		index, ok := root.ChildMapper[lane]
		if ok {
			root = root.ChildNodes[index]
			continue
		}

		node := &TreeNode{
			Val:         lane,
			ChildNodes:  nil,
			ChildMapper: make(map[string]int),
		}
		root.ChildNodes = append(root.ChildNodes, node)
		root.ChildMapper[lane] = len(root.ChildNodes) - 1
		root = node
	}
}

func (lt *TreeNode) RandomNodes(size int) []*TreeNode {
	rand.Seed(time.Now().UnixNano())
	rand.Shuffle(len(lt.ChildNodes), func(i, j int) {
		lt.ChildNodes[i], lt.ChildNodes[j] = lt.ChildNodes[j], lt.ChildNodes[i]
	})

	if len(lt.ChildNodes) < size {
		size = len(lt.ChildNodes)
	}

	return lt.ChildNodes[:size]
}

func (lt *TreeNode) Beatify(players []string) string {
	items := strings.Split(lt.Val, ",")
	beatifies := make([]string, 0, len(items))
	for i, item := range items {
		beatifies = append(beatifies, NodeItemBeautifyTextMapper[i]+"-"+players[item[0]-'a'])
	}

	return strings.Join(beatifies, "\t")
}

func BuildLaneTree() (*TreeNode, error) {
	rawData, err := os.ReadFile(permutationsSourceFile)
	if err != nil {
		return &TreeNode{}, err
	}

	treeRoot := &TreeNode{
		Val:         "root",
		ChildNodes:  nil,
		ChildMapper: make(map[string]int),
	}
	lanes := strings.Split(string(rawData), "\n")
	for _, lane := range lanes {
		if strings.TrimSpace(lane) == "" {
			continue
		}

		treeRoot.AddLanes(lane)
	}

	return treeRoot, nil
}
